import logging

from openlbsserver.lib.base import *

from formencode import schema, validators, Invalid, FancyValidator

from openlbsserver.model import meta
from openlbsserver.model import User

import re
import hashlib

log = logging.getLogger(__name__)


def salt_pass(password):
    m = hashlib.sha256()
    
    salt = h.gen_session_key()
    m.update(password)
    m.update(salt)
    return salt, m.hexdigest()
    
    
def user_exists(usr):
    try:
        meta.Session.query(User).filter_by(username=usr).one()
    except:
        return False
        
    return True
    
def email_exists(email):
    try:
        meta.Session.query(User).filter_by(email=email).one()
    except:
        return False
        
    return True

class UsernameValidator(FancyValidator):
    def _to_python(self, value, state):
        p = re.compile(r'^[A-Za-z0-9_.]+$')
        if p.match(value):
            if user_exists(value):
                raise Invalid(_('The username you specified is already taken.'), value, state)
            else:
                return value
        else:
            raise Invalid(_('Username must only contain letters, numbers, underscore, or period.'), value, state)
            
class EmailValidator(validators.Email):

    def _to_python(self, value, state):
        if email_exists(value):
            raise Invalid(_('The email you specified is already taken.'), value, state)
        else:
            return value

class RegisterForm(schema.Schema):
    allow_extra_fields = True
    
    username = UsernameValidator(not_empty=True,max=50)
    password = validators.String(not_empty=True,max=50)
    password1 = validators.String(not_empty=True,max=50)
    email = EmailValidator(not_empty=True,max=64)

class RegisterController(BaseController):

    def start(self):
        return render('register')
        
    def register_post(self):
        try:
            result = RegisterForm.to_python(request.POST)
            
            # create user
            usr = User()
            usr.email = result['email']
            usr.username = result['username']
            salt, password = salt_pass(result['password'])
            usr.salt = salt
            usr.password = password
            
            meta.Session.save(usr)
            meta.Session.commit()
            
            return render('register_finish')
            
        except Invalid, err:
            c.errors = err.error_dict
            
            return render('register')
        except Exception, msg:
            print msg
            abort(404)